package com.xialinrui.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xialinrui.dto.TodoCompletedDto;
import com.xialinrui.entity.Affair;
import com.xialinrui.entity.ResponseResult;
import com.xialinrui.entity.Todo;
import com.xialinrui.mapper.TodoMapper;
import com.xialinrui.service.TodoService;
import com.xialinrui.vo.TodoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xialinrui
 */
@Service
@Transactional
public class TodoServiceImpl extends ServiceImpl<TodoMapper, Todo> implements TodoService {

    @Resource
    private TodoMapper todoMapper;

    @Override
    public Long saveWithName(TodoVo todoVo) {
        //新建一个Todo任务对象
        Todo todo = new Todo();
        BeanUtils.copyProperties(todoVo, todo, "areaDetailPre");
        //得到区块层级id
        List<Long> areaDetailPre = todoVo.getAreaDetailPre();
        List<String> tmpList = areaDetailPre.stream().map((item) -> {
            String tmp = Long.toString(item);
            return tmp;
        }).collect(Collectors.toList());
        String areaDetail = String.join("_", tmpList);
        todo.setAreaDetail(areaDetail);
        LambdaQueryWrapper<Todo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Todo::getAreaId, areaDetailPre);
        List<Todo> todos = this.list(queryWrapper);
        List<String> titleList = todos.stream().map((item) -> {
            String title = item.getTitle();
            return title;
        }).collect(Collectors.toList());
        titleList.add(todo.getTitle());
        todo.setName(String.join("_", titleList));
        this.save(todo);
        return todo.getId();
    }

    @Override
    public ResponseResult deleteTodo(Todo todo) {
        //如果不是文件夹
        if (todo.getType() == 1) {
            List<Affair> todoInsertedList = getTodoInsertedList(todo.getId());
            if (todoInsertedList.size() == 0) {
                todoMapper.deleteById(todo);
                return new ResponseResult<>(200, "删除成功");
            }
            return new ResponseResult<>(201, "你曾经在某天某个时间段做过这个任务哦，坚持下去吧！");
        }
        //如果是文件夹，先获取所有要删除的内容
        String areaDetail = todo.getAreaDetail();
        QueryWrapper<Todo> todoQueryWrapper = new QueryWrapper<>();
        todoQueryWrapper.likeRight("area_detail", areaDetail)
                .eq("todo_category_id", todo.getTodoCategoryId());
        List<Todo> list = list(todoQueryWrapper);
        ArrayList<Todo> newList = new ArrayList<>();
        for (Todo cur : list) {
            if (cur.getType() == 1 && getTodoInsertedList(cur.getId()).size() == 0) {
                todoMapper.deleteById(cur);
                continue;
            }
            newList.add(cur);
        }
        Boolean delFolder = true;
        for (Todo cur : newList) {
            if (cur.getType() == 1) {
                delFolder = false;
                break;
            }
        }
        if (delFolder == true) {
            for (Todo cur : newList) {
                todoMapper.deleteById(cur);
            }
            return new ResponseResult<>(200, "删除成功");
        }
        return new ResponseResult<>(202, "你曾经在某天某个时间段做过这个文件夹下的某个任务哦，坚持下去吧！");
    }


    @Override
    public void adjust(Todo todo) {
        if (todo.getType() == 1) {
            flushName(todo);
            todoMapper.updateById(todo);
            return;
        }
        String areaDetail = todo.getAreaDetail();
        QueryWrapper<Todo> todoQueryWrapper = new QueryWrapper<>();
        todoQueryWrapper.likeRight("area_detail", areaDetail);
        List<Todo> todos = this.list(todoQueryWrapper);
        for (Todo item : todos) {
            flushName(item);
            todoMapper.updateById(item);
        }
    }

    @Override
    public void changeComplete(Long todoId, Long affairId) {
        todoMapper.changeComplete(todoId, affairId);
        Todo todo = this.getById(todoId);
        String[] area = todo.getAreaDetail().split("_");
        //如果不在任何一个文件夹内，直接结束，返回即可
        if (area.length == 1 || todo.getTodoCategoryId().equals(0))  {
            return;
        }
        //用来查询父节点的detail
        StringBuffer parent = new StringBuffer();
        for (int i = 0; i <= area.length - 2; i++) {
            if (i == 0) {
                parent.append(area[i]);
            } else {
                parent.append("_" + area[i]);
            }
        }
        //查询出这个父节点下所有的
        QueryWrapper<Todo> todoQueryWrapper = new QueryWrapper<>();
        todoQueryWrapper.likeRight("area_detail", parent);
        List<Todo> todos = this.list(todoQueryWrapper);
        Boolean toCancelTheFolder = true;
        ArrayList<Long> ids = new ArrayList<>();
        for (TodoCompletedDto todoCompletedDto : getCompletedTodoListWithOutDaily()) {
            ids.add(todoCompletedDto.getId());
        }
        for (Todo cur : todos) {
            if (cur.getType() == 0) {
                continue;
            }
            if (!ids.contains(cur.getId())) {
                toCancelTheFolder = false;
                break;
            }
        }
        if (toCancelTheFolder) {
            QueryWrapper<Todo> todoQueryWrapper1 = new QueryWrapper<>();
            todoQueryWrapper1.eq("area_detail", parent.toString());
            Todo one = this.getOne(todoQueryWrapper1);
            one.setIsCanceled(1);
            this.updateById(one);
        }
    }

    @Override
    public List<Affair> getTodoInsertedList(Long id) {
        return todoMapper.getTodoInsertedList(id);

    }

    @Override
    public void setIncomplete(Long id) {
        todoMapper.setIncomplete(id);
    }

    @Override
    public List<Todo> getIncompleteTodoListWithOutDailyByCategoryId(Long id) {
        return todoMapper.getIncompleteTodoListWithOutDailyByCategoryId(id);
    }

    @Override
    public List<Todo> getTodoListIncomplete() {
        return todoMapper.getTodoListIncomplete();
    }

    @Override
    public List<Todo> listDailyNotCompletedToday(Date date) {
        return todoMapper.listDailyNotCompletedToday(date);
    }

    @Override
    public List<Todo> listDailyCompletedToday(Date date) {
        return todoMapper.listDailyCompletedToday(date);
    }

    @Override
    public List<TodoCompletedDto> getCompletedTodoListWithOutDaily() {
        return todoMapper.getCompletedTodoListWithOutDaily();
    }


    @Override
    public List<Todo> getTodoListIncompleteDaily(Date date) {
        return todoMapper.getTodoListIncompleteDaily(date);
    }

    @Override
    public void changeComplete(Long todoId, Long affairId, Long incomeId) {
        todoMapper.insertIncome(todoId, affairId, incomeId);
    }

    @Override
    public Long getCompletedTodoIncomeId(Long id) {
        return todoMapper.getCompletedTodoIncomeId(id);
    }

    @Override
    public Page<Todo> getIncompleteTodoListWithOutDailyByCategoryIdNotFolders(Page<Todo> page, Long id) {
        return todoMapper.getIncompleteTodoListWithOutDailyByCategoryIdNotFolders(page, id);
    }

    @Override
    public List<Date> getAllDate() {

        return todoMapper.getAllDate();
    }

    @Override
    public List<Todo> getIncompleteTodoListWithOutDailyByCategoryIdNotFoldersNoPage(Long id) {
        return todoMapper.getIncompleteTodoListWithOutDailyByCategoryIdNotFoldersNoPage(id);
    }

    @Override
    public void defaultAcquire(Long id, Double money, Integer love) {
        todoMapper.defaultAcquire(id, money, love);
    }


    public void flushName(Todo todo) {
        ArrayList<Long> areaDetailPre = new ArrayList<>();
        String[] areaDetail = todo.getAreaDetail().split("_");
        for (String str : areaDetail) {
            areaDetailPre.add(Long.parseLong(str));
        }
        List<String> titleList = new ArrayList<>();
        for (Long areaId : areaDetailPre) {
            QueryWrapper<Todo> todoQueryWrapper = new QueryWrapper<>();
            todoQueryWrapper.eq("area_id", areaId);
            Todo one = this.getOne(todoQueryWrapper);
            titleList.add(one.getTitle());
        }
        todo.setName(String.join("_", titleList));
    }


}
